package com.zjw.study.thread06_return;

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import com.zjw.study.thread.ThreadUtils;

/**
 * 有返回值的线程
 * @author Administrator
 *
 */
public class ThreadFuture {
	public static void main(String[] args) {
		ThreadFuture future = new ThreadFuture();
//		future.future01();
//		future.future01_runnable();
//		future.future02();
		future.completionService();
	}
	
	/**
	 * 获取返回值
	 */
	void future01() {
		ExecutorService threadPool = Executors.newSingleThreadExecutor();
		//使用submit方法，而不是execute
		Future<String> future = threadPool.submit(new Callable<String>() {
			@Override
			public String call() throws Exception {
				ThreadUtils.sleep(3000);
				return "future call submit...";
			}
		});
		
		System.out.println("****** 等待结果 ******");
		try {
			System.out.println(future.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		threadPool.shutdown();
	}
	/**
	 * 使用Runnable方式，返回值建议用对象，基本类型不方便传值
	 */
	void future01_runnable() {
		class User {
			String username;
		}
		
		final User user = new User();
		ExecutorService threadPool = Executors.newSingleThreadExecutor();
		Future<User> future = threadPool.submit(new Runnable() {
			@Override
			public void run() {
				user.username = "zjw";
				System.out.println("execute");
				ThreadUtils.sleep(2000);
			}
		}, user);
		
		System.out.println("****** 等待结果 ******");
		try {
			System.out.println(future.get().username);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		threadPool.shutdown();
		
	}
	
	/**
	 * 获取返回值，设置最大等待时长
	 */
	void future02() {
		ExecutorService threadPool = Executors.newSingleThreadExecutor();
		//使用submit方法，而不是execute
		Future<String> future = threadPool.submit(new Callable<String>() {
			@Override
			public String call() throws Exception {
				ThreadUtils.sleep(3000);
				return "future call submit...";
			}
		});
		System.out.println("****** 等待结果 ******");
		try {
			System.out.println(future.get(1, TimeUnit.SECONDS));//指定等待时长，超时抛出TimeoutException异常
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		} catch (TimeoutException e) {
			//超时异常
			e.printStackTrace();
		}
		threadPool.shutdown();
	}
	
	/**
	 * 谁先完成取谁的返回值
	 */
	void completionService() {
		ExecutorService executor = Executors.newFixedThreadPool(10);
		CompletionService<Integer> completions = new ExecutorCompletionService<>(executor);
		for (int i = 0; i < 10; i++) {
			final int executeSequence = i;
			completions.submit(new Callable<Integer>() {
				@Override
				public Integer call() throws Exception {
					ThreadUtils.sleep(new Random().nextInt(5000));
					return executeSequence;
				}
			});
		}
		
		System.out.println("+++++++++ 等待结果 ++++++++");
		for (int i = 0; i < 10; i++) {
			try {
				System.out.println(completions.take().get());
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
		}
	}

}
